import bat.ke.qq.com.AppConfig;
import bat.ke.qq.com.bean.Fox;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.*;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

import java.util.Arrays;

/**
 * bean 的注册原理
 */
@Slf4j
public class IoCTest2 {

    /**
     * bean 的注册原理：java Configuration demo
     */
    @Test
    public void test() {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        // NoSuchBeanDefinitionException
        context.getBean("user");
        context.getBean("userService");
    }


    /**
     * bean 的注册原理：
     */
    @Test
    public void testXml() {
//        ApplicationContext  context =  new ClassPathXmlApplicationContext("spring.xml");
//        //   beanDefinitionMap   beanName: beanDefinition
//        System.out.println(Arrays.toString(context.getBeanDefinitionNames()));
//        System.out.println(context.getBean("user"));
        ResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource resource = resourceLoader.getResource("spring.xml");
        // 创建一个简单注册器
        // BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
        /**
         * 注册 beanDefinition 的核心逻辑：通过调用 {@link DefaultListableBeanFactory#registerBeanDefinition}
         * 方法将bean的beanName----beanDefinition注册到beanFactory的beanDefinitionMap中
         */
        // 创建一个实现了注册器的工厂
        DefaultListableBeanFactory registry = new DefaultListableBeanFactory();
        // 创建bean定义读取器
        BeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);
        reader.loadBeanDefinitions(resource);
        log.info(Arrays.toString(registry.getBeanDefinitionNames()));
        // 注册 beanDefinition
        BeanDefinition beanDefinition = new RootBeanDefinition(Fox.class);
        // 填充属性
        beanDefinition.getPropertyValues().add("name", "fox");
        //beanDefinition.setBeanClassName("bat.ke.qq.com.bean.User");
        // beanDefinitionMap.put("fox",beanDefinition)
        // 注册 BeanDefinition 的核心逻辑
        registry.registerBeanDefinition("fox", beanDefinition);
        log.info(Arrays.toString(registry.getBeanDefinitionNames()));
        // Fox  beanFactory   最最最核心： DefaultListableBeanFactory
        log.info(registry.getBean("userService").toString()); // Fox  User
    }
}
